package GUI;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

import model.Hero;
import model.Map;
import model.Player;
import model.Spy;
import model.TechnologyLevel;
import model.Territory;

public class MapPanel extends JPanel{

	/**
	 * 
	 */
	private static final long serialVersionUID = 5733193721805182082L;
	private final MapPanel mapPanel;
	private ArrayList<TerritoryPanel> territoryGrid;
	private final Map map;
	private final Player player;
	private TextPanel textPanel;
	
	public MapPanel(Player player, Map map){	   
	    this.map = map;
	    this.player = player;
	    mapPanel = this;
	  	this.setLayout(new GridLayout(5, 5, 2, 2));	 //david change it 
	  	this.setBorder (BorderFactory.createEtchedBorder ());
	  
	  	territoryGrid = new ArrayList<TerritoryPanel>();   //david change it
	  	   for (int i = 0; i < 5; i++)
	  		   for (int j = 0; j < 5; j++){
	   			   TerritoryPanel t = new TerritoryPanel(map.getTerritory(i * 5 + j));
				   territoryGrid.add(t);
	  			   this.add(t);
	  		   } //david rewrite this
	}
	     
	public void setTextPanel(TextPanel textPanel){this.textPanel = textPanel;}
	public Player getPlayer(){return player;}
	
	public TerritoryPanel getTerritoryPanel(Territory territory){
		int location = territory.getLocation();
		return territoryGrid.get(location);
	}
	
	public void clearBorder(){
	   	 for (TerritoryPanel tp : territoryGrid)
	    	 tp.setBorder(BorderFactory.createEmptyBorder());
	 }
         
	public class TerritoryPanel extends JPanel{
		/**
		 * 
		 */
		private static final long serialVersionUID = 2253469906002191810L;
		private Territory territory;
		private Hero owner;
        private TerritoryPanel territoryPanel;
        private JPopupMenu popupMenu;
        private JMenuItem moveTroopMenuItem, attackEnemyMenuItem, createSpyMenuItem, moveSpyMenuItem, convertBackSpyMenuItem, upgradeTroopMenuItem;
             
	    public TerritoryPanel(Territory territory){
	    	  this.territory = territory;
	    	  territoryPanel = this;
	    	  owner = territory.getOwner();
	    	  this.add(new JLabel(String.valueOf(territory.getLocation())));
	    	  this.setBackground(territory.getOwner().getColor());
	     
	    	  popupMenu = new JPopupMenu();
	    	  moveTroopMenuItem = new JMenuItem("Move troop");
	    	  moveTroopMenuItem.addActionListener(new moveTroopListener());
	    	  attackEnemyMenuItem = new JMenuItem("Attack enemy");
	    	  attackEnemyMenuItem.addActionListener(new attackEnemyListener());
	    	  upgradeTroopMenuItem = new JMenuItem("Upgrade troop");
	    	  upgradeTroopMenuItem.addActionListener(new upgradeTroopListener());
	    	  createSpyMenuItem = new JMenuItem("Create spy");
	    	  createSpyMenuItem.addActionListener(new createSpyListener());
	    	  moveSpyMenuItem = new JMenuItem("Move spy");
	    	  moveSpyMenuItem.addActionListener(new moveSpyListener());
	    	  convertBackSpyMenuItem = new JMenuItem("Convert Back Spy");
	    	  convertBackSpyMenuItem.addActionListener(new convertBackSpyListener());
	    	      
	    	  this.setToolTipText(getTips());
	    	  this.addMouseListener(new popupMenuListener());
             }
	    
	    public void update(){
	    	  popupMenu.removeAll();
	    	  if (owner == player){
	    		  popupMenu.add(moveTroopMenuItem);
	    	   	  popupMenu.add(attackEnemyMenuItem);
	    	   	  popupMenu.add(upgradeTroopMenuItem);
	    	  	  popupMenu.add(createSpyMenuItem);
	    	  	  if (player.hasSpy(territory))
	    	  		  popupMenu.add(convertBackSpyMenuItem);
	    	      }
	    	  if (player.hasSpy(territory))
	    	   	popupMenu.add(moveSpyMenuItem); 
	    	
	    	  this.setToolTipText(getTips());
	    }
	    public String getTips(){
	        String strtemp = new String();
	        strtemp +=  "<html>" + "<b>";
	        strtemp += "Location: " + territory.getLocation() + "<br>";
	        strtemp += "Owner: " + owner.getName() + "<br>";
	        strtemp += "My spy: ";
	        if (!player.hasSpy(territory))
	        	strtemp += " N/A";
	        else
	          for (Spy spy: player.getSpyList())
	        	 if (spy.getTerritory() == territory)
	        	  	 strtemp += spy.getLevel().toString() + ", ";
	        strtemp += "<br>";
	        strtemp += "Food Unit: " + territory.getFoodUnit() + "     " + "Technology Unit: " + territory.getTechnologyUnit();
	        strtemp += "<br>";
	        for (TechnologyLevel level:TechnologyLevel.values())
		  		strtemp += level.toString() + ": " +territory.getTroopAmount(level) 
		   		           + " (Usable: " + territory.getUsableTroopAmount(level) + ") "
		   		           + "<br>";		            				    
	        strtemp +=  "</b>" + "</html>";
	        return (strtemp);
	    }
	    		
	    public Territory getTerritory(){return territory;}
	    public MapPanel getMapPanel(){return mapPanel;}
	    public Player getPlayer(){return player;}
	    class popupMenuListener extends MouseAdapter{
	        public void mousePressed(MouseEvent e) {
    			mapPanel.clearBorder();
	    		territoryPanel.setBorder(BorderFactory.createLineBorder (Color.black, 3));
	    		if (e.isPopupTrigger()){
	    			territoryPanel.update();
	    			popupMenu.show(e.getComponent(),e.getX(),e.getY());
	    		}
	    	}
	    	
	        public void mouseReleased(MouseEvent e) {
	        	mapPanel.clearBorder();
	    		territoryPanel.setBorder(BorderFactory.createLineBorder (Color.black, 3));
	        	if (e.isPopupTrigger()){
		    		  territoryPanel.update();
	        		  popupMenu.show(e.getComponent(),e.getX(),e.getY());
		    		}
	    	}
	        public void mouseClicked(MouseEvent ev) {}
	    }
	     
	    class moveSpyListener implements ActionListener{
	    			public void actionPerformed(ActionEvent arg0) {
	    				new MoveSpyFrame(textPanel, territoryPanel, map);
	    				textPanel.updatePlayerPanel();
	    				territoryPanel.update();
	    			}
	    		}
	    		
	    class createSpyListener implements ActionListener{
	    			public void actionPerformed(ActionEvent arg0) {
	    				  new CreateSpyFrame(textPanel, territoryPanel, map);
	    				  textPanel.updatePlayerPanel();
	    				  territoryPanel.update();
	    			}
	    		}
	    
	    class convertBackSpyListener implements ActionListener{
	    			public void actionPerformed(ActionEvent arg0) {
	    				  new ConvertBackSpyFrame(textPanel, territoryPanel, map);
	    				  textPanel.updatePlayerPanel();		
	    				  territoryPanel.update();
	    			}
	    		}
	    		
	    class upgradeTroopListener implements ActionListener{
 	    			  public void actionPerformed(ActionEvent arg0) {
	    				new UpgradeTroopFrame(textPanel, territoryPanel, map);
	    				textPanel.updatePlayerPanel();  
	    				territoryPanel.update();
	    			  }
	    		  }
	    		
	    class moveTroopListener implements ActionListener{
	    			  public void actionPerformed(ActionEvent arg0) {
	    				  new MoveFrame(textPanel, territoryPanel, map);
	    				  textPanel.updatePlayerPanel();
	    				  territoryPanel.update();
	    			  }
	    		 }
	    		
	    class attackEnemyListener implements ActionListener{
	    			  public void actionPerformed(ActionEvent arg0) {
	    				  new AttackFrame(textPanel, territoryPanel, map);
	    				  textPanel.updatePlayerPanel();
	    				  territoryPanel.update();
	    				}
	    		  }	
	 }
}




